package Test1;

import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

public class Quick {

    public static void main(String[] args) throws IOException, InterruptedException {
//         //阻塞队列的基本使用
//        ArrayBlockingQueue<String> list = new ArrayBlockingQueue<>(1);
//
//        A a = new A(list);
//
//        B b = new B(list);
//
//        a.start();
//        b.start();

//        创建线程池,ExecutorService可以代替我们操作线程池，所以我们只需要控制ExecutorService就好。
//        ExecutorService executorService = Executors.newCachedThreadPool();
//
//        executorService.submit(()->{
//            System.out.println(Thread.currentThread().getName()+" aaaaa");
//        });
//     Thread.sleep(1000);
//        executorService.submit(()->{
//            System.out.println(Thread.currentThread().getName()+" bbbbb");
//        });
//        executorService.shutdown();

//          创建线程池
//        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
//                2,  //核心线程个数
//                5,  //最大线程个数
//                2,  //最大生命周期，配合下面的单位使用
//                TimeUnit.HOURS, //生命周期的单位，例如hours加上2的最大生命周期就是2小时
//                new ArrayBlockingQueue<>(10),   //创建阻塞队列
//                Executors.defaultThreadFactory(),   //创建线程工厂，底层就是帮助我们创建线程，Thread t1 = new Thread
//                new ThreadPoolExecutor.AbortPolicy()    //当线程超过最大线程加上阻塞队列的和的时候，多余线程会移除并且抛出错误。
//        );
//             线程的原子性，利用AtomicInteger，调用其中方法。
//            MyThread my = new MyThread();
//
//        for (int i = 0; i < 100; i++) {
//            new Thread(my).start();
//        }



//        当我们需要用到某一些线程执行后才开启的线程时，可以使用CountDownLatch来控制开启线程的个数，并且使其他线程等待。
//        CountDownLatch count = new CountDownLatch(2);
//
//         Mom m = new Mom(count);
//        Children c =new Children(count);
//        Children2 c2 = new Children2(count);
//        new Thread(c2).start();
//         m.start();
//         c.start();


//          使用Semaphore去控制可允许的线程数量，利用acquire去获得线程使用权，使用release去释放归还线程权限
//          Myrun myrun = new Myrun();
//
//        for (int i = 0; i < 30; i++) {
//            new Thread(myrun).start();
//        }


    }

}


class Myrun implements Runnable{

    private Semaphore semaphore = new Semaphore(5);
    @Override
    public void run() {

        try {
            semaphore.acquire();

            System.out.println("拿走一个通行证");

            Thread.sleep(2000);

            System.out.println("归还通行证");
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

class Children extends Thread{

    private CountDownLatch count;
    public Children(CountDownLatch count) {
        this.count=count;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            System.out.println("吃东西！ "+i);
        }

        count.countDown();
    }
}
class Children2 implements Runnable{

    private CountDownLatch count;
    public Children2(CountDownLatch count) {
        this.count=count;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 15; i++) {
            System.out.println("喝水！ "+i);
        }

        count.countDown();
    }
}
class Mom extends Thread{

    private CountDownLatch count;
    public Mom(CountDownLatch count) {
        this.count=count;
    }

    @Override
    public void run() {

        try {
            count.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("收拾碗筷");
    }
}


class MyThread implements Runnable{

    AtomicInteger ac = new AtomicInteger(0);
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            int increment = ac.incrementAndGet();
            System.out.println(increment);
        }
    }
}

class A extends Thread{

    private ArrayBlockingQueue<String> list;

    public A(ArrayBlockingQueue<String> list) {
        this.list=list;

    }

    @Override
    public void run() {
        while(true) {
            try {
                list.put("food");
                System.out.println("put food");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

class B extends Thread{

    private ArrayBlockingQueue<String> list;

    public B(ArrayBlockingQueue<String> list) {
        this.list=list;
    }

    @Override
    public void run() {
        while(true) {
            try {
                String take = list.take();
                System.out.println("get"+take);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}